﻿using System;
using System.Collections.Specialized;
using System.Reflection;
using System.Web.UI.WebControls;
using JUtil;
using JUtil.Extensions;
using JUtil.Web.Extensions;

public interface IMasterView
{
    void SetSelectParameters();

    void DoDataBind();

    object GetUI();

    object GetDataSource();

    Type GetDalType();

    object BLL { get; }
}

public interface IDetailView
{
    void HideDetail();
}

/// <summary>
/// XPage 的摘要描述
/// </summary>
public class XPage
    : System.Web.UI.Page
{
    public XPage()
    {
        this.Load += new EventHandler(XPage_Load);
    }

    void XPage_Load(object sender, EventArgs e)
    {
        AttachEvents();
    }

    protected void QueryMaster()
    {
        if (!HasMasterInterface) return;

        MasterInterface.SetSelectParameters();

        MasterInterface.DoDataBind();
    }

    protected void QueryDetail(OrderedDictionary od)
    {

    }

    protected bool HasMasterInterface
    {
        get { return this is IMasterView; }
    }

    protected IMasterView MasterInterface
    {
        get { return this as IMasterView; }
    }

    protected bool HasDetailInterface
    {
        get { return this is IDetailView; }
    }

    protected IDetailView DetailInterface
    {
        get { return this as IDetailView; }
    }

    protected void AttachEvents()
    {
        AttachMasterEvents();
    }

    protected void AttachMasterEvents()
    {
        if (!HasMasterInterface) return;

        object UI = MasterInterface.GetUI();
        Type uiType = UI.GetType();
        switch (uiType.Name)
        {
            case "GridView":
                {
                    GridView grv = UI as GridView;

                    grv.SelectedIndexChanged += new EventHandler(grv_SelectedIndexChanged);
                    grv.PageIndexChanged += new EventHandler(grv_PageIndexChanged);
                    grv.RowDeleting += new GridViewDeleteEventHandler(grv_RowDeleting);
                    grv.RowDeleted += new GridViewDeletedEventHandler(grv_RowDeleted);
                } break;
        }
        
        object DataSource = MasterInterface.GetDataSource();
        Type dataSourceType = DataSource.GetType();
        switch (dataSourceType.Name)
        {
            case "ObjectDataSource":
                {
                    ObjectDataSource dsMaster = DataSource as ObjectDataSource;

                    dsMaster.ObjectCreating += new ObjectDataSourceObjectEventHandler(dsMaster_ObjectCreating);
                } break;
        }
    }

    #region grv_RowDeleted
    void grv_RowDeleted(object sender, GridViewDeletedEventArgs e)
    {
        try
        {
            // 不論成功與否都重新Bind
            QueryMaster();

            if (HasDetailInterface)
                DetailInterface.HideDetail();

            // 如果有錯誤發生，就顯示出來
            if (e.Exception != null)
            {
                Log.ReportError(e.Exception);

                e.ExceptionHandled = true;
            }
        }
        catch (Exception ex)
        {
        	Log.ReportError(ex);
        }
    }
    #endregion
    #region grv_RowDeleting
    void grv_RowDeleting(object sender, GridViewDeleteEventArgs e)
    {
        try
        {
            GridView grv = (GridView)sender;

            GridViewRow row = grv.Rows[e.RowIndex];

            OrderedDictionary od = row.ExtractValues();

            Type dalType = MasterInterface.GetDalType();

            object aRec = od.ConvertTo(dalType);

            foreach (PropertyInfo pi in dalType.GetProperties())
            {
                object value = pi.GetValue(aRec, null);

                e.Keys[pi.Name] = value;
            }
        }
        catch (Exception ex)
        {
        	Log.ReportError(ex);
        }
    }
    #endregion
    #region grv_PageIndexChanged
    void grv_PageIndexChanged(object sender, EventArgs e)
    {
        try
        {
            QueryMaster();

            if (HasDetailInterface)
                DetailInterface.HideDetail();
        }
        catch (Exception ex)
        {
        	Log.ReportError(ex);
        }
    }
    #endregion
    #region grv_SelectedIndexChanged
    void grv_SelectedIndexChanged(object sender, EventArgs e)
    {
        try
        {
            GridView grv = (GridView)sender;

            OrderedDictionary od = grv.ExtractSelectedValues();

            QueryDetail(od);
        }
        catch (Exception ex)
        {
        	Log.ReportError(ex);
        }
    }
    #endregion

    #region dsMaster_ObjectCreating
    void dsMaster_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
    {
        e.ObjectInstance = MasterInterface.BLL;
    }
    #endregion
}
